using System;
using System.IO;
using System.Text;

using Multiplicity.Runtime.Serialization.Binary;

namespace Multiplicity.Reflection {
    public sealed class StorageHeader {

        const uint MetadataSignature = 0x424a5342;

        uint magic = 0;

        public Version MetadataVersion;
        public string RuntimeVersion;
        public StorageHeapHeader[] Heaps;

        public StorageHeader() {
        }

        public static StorageHeader Parse(BinaryParser br) {

            uint signature = br.ReadUInt32();
            if (signature != MetadataSignature) {
                MetadataException.ThrowInvalidHeader();
            }

            StorageHeader hdr = new StorageHeader();
            
            hdr.MetadataVersion = new Version(br.ReadUInt16(), br.ReadUInt16());
            br.ReadUInt32(); // hdr.ExtraData 

            int verNameLen = Convert.ToInt32(br.ReadUInt32());
            byte[] verNameBuff = br.ReadBytes(verNameLen);
            hdr.RuntimeVersion = Encoding.ASCII.GetString(verNameBuff);

            br.ReadByte(); // hdr.StorageFlags 
            br.ReadByte(); // padding

            hdr.Heaps = new StorageHeapHeader[br.ReadUInt16()];
            for (int i = 0; i < hdr.Heaps.Length; i++) {
                hdr.Heaps[i] = br.ReadRecord<StorageHeapHeader>();
            }

            return hdr;
        }
    }

    [BinaryRecord(Pack=4)]
    public sealed class StorageHeapHeader {

        public uint Offset;
        public uint Size;
        [BinaryField(BinaryFieldType.StringAsciiZ)]
        public string Name;
    }
}
